/*
 * (C) Copyright 2010
 * NVIDIA Corporation <www.nvidia.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#ifndef INCLUDED_NVBOOT_BIT_H
#define INCLUDED_NVBOOT_BIT_H

#include "nvcommon.h"
#include "nvboot_config.h"
#include "nvboot_osc.h"

#if defined(__cplusplus)
extern "C"
{
#endif

////////////////////////////////////////////////
// excerpted from nvboot_bct.h
////////////////////////////////////////////////

/**
 * Identifies the types of devices from which the system booted.
 * Used to identify primary and secondary boot devices.
 * @note These no longer match the fuse API device values (for
 * backward compatibility with AP15).
 */
typedef enum
{
    /// Specifies a default (unset) value.
    NvBootDevType_None = 0,

    /// Specifies NAND.
    NvBootDevType_Nand,

    /// Specifies an alias for 8-bit NAND.
    NvBootDevType_Nand_x8 = NvBootDevType_Nand,

    /// Specifies SNOR.
    NvBootDevType_Snor,

    /// Specifies an alias for NOR.
    NvBootDevType_Nor = NvBootDevType_Snor,

    /// Specifies SPI NOR.
    NvBootDevType_Spi,

    /// Specifies SDMMC (either eMMC or eSD).
    NvBootDevType_Sdmmc,

    /// Specifies internal ROM (i.e., the BR).
    NvBootDevType_Irom,

    /// Specifies UART (only available internal to NVIDIA).
    NvBootDevType_Uart,

    /// Specifies USB (i.e., RCM).
    NvBootDevType_Usb,

    /// Specifies 16-bit NAND.
    /// @note Not used in AP20 - just _Nand.
    NvBootDevType_Nand_x16,

    /// Specifies MuxOneNAND or FlexMuxOneNAND.
    NvBootDevType_MuxOneNand,

    /// Specifies mobileLBA NAND.
    NvBootDevType_MobileLbaNand,

    NvBootDevType_Max,

    /// Ignore -- Forces compilers to make 32-bit enums.
    NvBootDevType_Force32 = 0x7FFFFFFF
 } NvBootDevType;

////////////////////////////////////////////////

/// Specifies the amount of status data needed in the BIT.
/// One bit of status is used for each of the journal blocks,
/// and 1 additional bit is needed for the second BCT in block 0.
#define NVBOOT_BCT_STATUS_BITS  (NVBOOT_MAX_BCT_SEARCH_BLOCKS + 1)
#define NVBOOT_BCT_STATUS_BYTES ((NVBOOT_BCT_STATUS_BITS + 7) >> 3)

/**
 * Defines the type of boot.
 * Note: There is no BIT for warm boot.
 */
typedef enum
{
    /// Specifies a default (unset) value.
    NvBootType_None = 0,

    /// Specifies a cold boot
    NvBootType_Cold,

    /// Specifies the BR entered RCM
    NvBootType_Recovery,

    /// Specifies UART boot (only available internal to NVIDIA)
    NvBootType_Uart,

    NvBootType_Force32 = 0x7fffffff    
} NvBootType;

/**
 * Defines the status codes for attempting to load a BL.
 */
typedef enum
{
    /// Specifies a default (unset) value.
    NvBootRdrStatus_None = 0,

    /// Specifies a successful load.
    NvBootRdrStatus_Success,

    /// Specifies validation failure.
    NvBootRdrStatus_ValidationFailure,

    /// Specifies a read error.
    NvBootRdrStatus_DeviceReadError,

    NvBootRdrStatus_Force32 = 0x7fffffff
} NvBootRdrStatus;

/**
 * Defines the information recorded about each BL.
 *
 * BLs that do not become the primary copy to load have status of None.
 * They may still experience Ecc errors if used to recover from ECC
 * errors of another copy of the BL.
 */
typedef struct NvBootBlStateRec
{
    /// Specifies the outcome of attempting to load this BL.
    NvBootRdrStatus Status;

    /// Specifies the first block that experienced an ECC error, if any.
    /// 0 otherwise.
    NvU32           FirstEccBlock;

    /// Specifies the first page that experienced an ECC error, if any.
    /// 0 otherwise.
    NvU32           FirstEccPage;

    /// Specifies the first block that experienced a correctable ECC error,
    /// if any. 0 otherwise. Only correctable errors that push the limits of
    /// the ECC algorithm are recorded (i.e., those very likely to become
    /// uncorrectable errors in the near future).
    NvU32           FirstCorrectedEccBlock;

    /// Specifies the first page that experienced a correctable ECC error,
    /// if any. 0 otherwise. Similar to FirstCorrectedEccBlock.
    NvU32           FirstCorrectedEccPage;

    /// Specifies if the BL experienced any ECC errors.
    NvBool          HadEccError;

    /// Specifies if the BL experienced any CRC errors.
    NvBool          HadCrcError;

    /// Specifies if the BL experienced any corrected ECC errors.
    /// As with FirstCorrectedEcc*, only nearly-uncorrectable errors count.
    NvBool          HadCorrectedEccError;

    /// Specifies if the BL provided data for another BL that experienced an
    /// ECC error.
    NvBool          UsedForEccRecovery;
} NvBootBlState;

/**
 * Defines the status from NAND
 */
typedef struct NvBootNandStatusRec
{
    ///
    /// Parameters specified by fuses or straps.
    ///

    /// Specifies the data width specified by fuses or straps.
    NvU32 FuseDataWidth;

    /// Specifies the # of address cycles specified by fuses or straps.
    NvU32 FuseNumAddressCycles;

    /// Specifies whether ONFI support was disabled by fuses or straps.
    NvU32 FuseDisableOnfiSupport;

    /// Specifies the ECC specified by fuses or straps.
    NvU32 FuseEccSelection;

    /// Specifies the page size offset specified by fuses or straps.
    NvU32 FusePageSizeOffset;

    /// Specifies the block size offset specified by fuses or straps.
    NvU32 FuseBlockSizeOffset;

    /// Specifies the pinmux selection specified by fuses or straps.
    NvU32 FusePinmuxSelection;

    /// Specifies the pin orderspecified by fuses or straps.
    NvU32 FusePinOrder;

    ///
    /// Parameters discovered during operation
    ///

    /// Specifies the discovered data width
    NvU32 DiscoveredDataWidth;

    /// Specifies the discovered # of address cycles
    NvU32 DiscoveredNumAddressCycles;

    /// Specifies the discovered ECC
    NvU32 DiscoveredEccSelection;

    ///
    /// Parameters provided by the device
    ///

    /// Specifies IdRead
    NvU32 IdRead;

    /// Specifies if the part is an ONFI device
    NvU32 IsPartOnfi;

    ///
    /// Information for driver validation
    ///

    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the # of pages whose read resulted in uncorrectable errors.
    NvU32 NumUncorrectableErrorPages;

    /// Specifies the # of pages whose read resulted in correctable errors.
    NvU32 NumCorrectableErrorPages;

    /// Specifies the max # of correctable errors encountered.
    NvU32 MaxCorrectableErrorsEncountered;
} NvBootNandStatus;

/**
 * Defines the status from mobileLBA NAND
 */
typedef struct NvBootMobileLbaNandStatusRec
{
    ///
    /// Parameters specified by fuses or straps.
    ///

    /// Specifies the data width specified by fuses or straps.
    NvU32 FuseDataWidth;

    /// Specifies the # of address cycles specified by fuses or straps.
    NvU32 FuseNumAddressCycles;

    /// Specifies whether the BCT was read from the SDA region of the device.
    NvU32 FuseReadBctFromSda;

    /// Specifies the pinmux selection specified by fuses or straps.
    NvU32 FusePinmuxSelection;

    /// Specifies the pin orderspecified by fuses or straps.
    NvU32 FusePinOrder;

    ///
    /// Parameters discovered during operation
    ///

    /// Specifies the discovered data width
    NvU32 DiscoveredDataWidth;

    ///
    /// Parameters provided by the device
    ///

    /// Specifies IdRead
    NvU32 IdRead;

    ///
    /// Information for driver validation
    ///

    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the # of pages whose read resulted in uncorrectable errors.
    NvU32 NumUncorrectableErrorPages;
} NvBootMobileLbaNandStatus;

/**
 * Defines the status from eMMC and eSD
 */
typedef struct NvBootSdmmcStatusRec
{
    ///
    /// Parameters specified by fuses or straps.
    ///

    /// Specifies the data width specified by fuses or straps.
    NvU32 FuseDataWidth;

    /// Specifies the card type specified by fuses or straps.
    NvU32 FuseCardType;

    /// Specifies the voltage rangespecified by fuses or straps.
    NvU32 FuseVoltageRange;

    /// Specifies whether boot mode was disabled by fuses or straps.
    NvU32 FuseDisableBootMode;

    /// Specifies the pinmux selection specified by fuses or straps.
    NvU32 FusePinmuxSelection;

    ///
    /// Parameters discovered during operation
    ///

    /// Specifies the discovered card type
    NvU32 DiscoveredCardType;

    /// Specifies the discovered voltage range
    NvU32 DiscoveredVoltageRange;

    /// Specifies the data width chosen to conform to power class constraints
    NvU32 DataWidthUnderUse;

    /// Specifies the power class chosen to conform to power class constraints
    NvU32 PowerClassUnderUse;

    ///
    /// Parameters provided by the device
    ///

    /// Specifies the card identification data.
    NvU32 Cid[4];
 
    ///
    /// Information for driver validation
    ///

    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the # of CRC errors
    NvU32 NumCrcErrors;

    /// Specifies whether the boot was attempted from a Boot Partition.
    NvU32 BootFromBootPartition;

    /// Specifies whether the bootmode read is successful.
    NvU32 BootModeReadSuccessful;
} NvBootSdmmcStatus;

/**
 * Defines the status from SNOR
 */
typedef struct 
{
    /// Specifies if 32bit mode was specified by fuses or straps
    NvU32 IsFuse32BitMode;

    /// Specifies if non-muxed mode was specified by fuses or straps
    NvU32 IsFuseNonMuxedMode;

    /// Specifies the chosen clock source
    NvU32 ClockSource;
    /// Specifies the chosen clock divider
    NvU32 ClockDivider;
    
    /// Specifies the block size in use
    NvU32 BlockSize;

    /// Specifies the page size in use
    NvU32 PageSize;

    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the last block read
    NvU32 LastBlockRead;
    /// Specifies the last page read
    NvU32 LastPageRead;
    
    /// Specifies the init status
    NvU32 InitStatus; 

    /// Specifies whether parameters successfully validated
    NvU32 ParamsValidated;
} NvBootSnorStatus;

/**
 * Defines the status from MuxOneNAND and FlexMuxOneNAND devices
 */
typedef struct 
{
    /// Specifies the block size specified by fuses or straps
    NvU32 FuseBlockSize;
    /// Specifies the page size specified by fuses or straps
    NvU32 FusePageSize;

    /// Specifies the chosen clock source
    NvU32 ClockSource;
    /// Specifies the chosen clock divider
    NvU32 ClockDivider;
    
    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the last block read
    NvU32 LastBlockRead;
    /// Specifies the last page read
    NvU32 LastPageRead;

    /// Specifies the boot status
    NvU32 BootStatus; 

    /// Specifies the init status
    NvU32 InitStatus; 

    /// Specifies whether parameters successfully validated
    NvU32 ParamsValidated;
} NvBootMuxOneNandStatus;

/**
 * Defines the status from SPI flash devices
 */
typedef struct 
{
    /// Specifies the chosen clock source
    NvU32 ClockSource;
    /// Specifies the chosen clock divider
    NvU32 ClockDivider;

    /// Specifies whether fast read was selected
    NvU32 IsFastRead;
    
    /// Specifies the number of pages read from the beginning.
    NvU32 NumPagesRead;

    /// Specifies the last block read
    NvU32 LastBlockRead;
    /// Specifies the last page read
    NvU32 LastPageRead;

    /// Specifies the boot status
    NvU32 BootStatus; 

    /// Specifies the init status
    NvU32 InitStatus; 

    /// Specifies the read status
    NvU32 ReadStatus;

    /// Specifies whether parameters successfully validated
    NvU32 ParamsValidated;
} NvBootSpiFlashStatus;

/**
 * Defines NvBootSecondaryDeviceStatus to be the union of the individual
 * status structures of all the supported secondary boot device types.
 */
typedef union NvBootSecondaryDeviceStatusRec
{
    /// Specifies the status from NAND
    NvBootNandStatus          NandStatus;

    /// Specifies the status from mobleLBA NAND
    NvBootMobileLbaNandStatus MLbaStatus;

    /// Specifies the status from eMMC and eSD
    NvBootSdmmcStatus         SdmmcStatus;

    /// Specifies the status from SNOR
    NvBootSnorStatus          SnorStatus;

    /// Specifies the status from MuxOneNAND and FlexMuxOneNAND
    NvBootMuxOneNandStatus    MuxOneNandStatus;

    /// Specifies the status from SPI flash
    NvBootSpiFlashStatus      SpiStatus;
} NvBootSecondaryDeviceStatus;

/**
 * Defines the BIT.
 *
 * Notes:
 * * SecondaryDevice: This is set by cold boot (and soon UART) processing.
 *   Recovery mode does not alter its value.
 * * BctStatus[] is a bit vector representing the cause of BCT read failures.
 *       A 0 bit indicates a validation failure
 *       A 1 bit indicates a device read error
 *       Bit 0 contains the status for the BCT at block 0, slot 0.
 *       Bit 1 contains the status for the BCT at block 0, slot 1.
 *       Bit N contains the status for the BCT at block (N-1), slot 0, which
 *       is a failed attempt to locate the journal block at block N.
 *       (1 <= N < NVBOOT_MAX_BCT_SEARCH_BLOCKS)
 * * BctLastJournalRead contains the cause of the BCT search within the
 *   journal block. Success indicates the search ended with the successful
 *   reading of the BCT in the last slot.  CRC and ECC failures are indicated
 *   appropriately. 
 */
typedef struct NvBootInfoTableRec
{
    ///
    /// Version information
    ///

    /// Specifies the version number of the BR code.
    NvU32               BootRomVersion;

    /// Specifies the version number of the BR data structure.
    NvU32               DataVersion;

    /// Specifies the version number of the RCM protocol.
    NvU32               RcmVersion;

    /// Specifies the type of boot.
    NvBootType          BootType;

    /// Specifies the primary boot device.
    NvBootDevType       PrimaryDevice;

    /// Specifies the secondary boot device.
    NvBootDevType       SecondaryDevice;

    ///
    /// Hardware status information
    ///

    /// Specifies the measured oscillator frequency.
    NvBootClocksOscFreq OscFrequency;

    /// Specifies whether the device was initialized.
    NvBool              DevInitialized;

    /// Specifies whether SDRAM was initialized.
    NvBool              SdramInitialized;

    /// Specifies whether the ForceRecovery AO bit was cleared.
    NvBool              ClearedForceRecovery;

    /// Specifies whether the FailBack AO bit was cleared.
    NvBool              ClearedFailBack;

    /// Specifies whether FailBack was invoked.
    NvBool              InvokedFailBack;

    ///
    /// BCT information
    ///

    /// Specifies if a valid BCT was found.
    NvBool              BctValid;

    /// Specifies the status of attempting to read BCTs during the
    /// BCT search process.  See the notes above for more details.
    NvU8                BctStatus[NVBOOT_BCT_STATUS_BYTES];

    /// Specifies the status of the last journal block read.
    NvBootRdrStatus     BctLastJournalRead;

    /// Specifies the block number in which the BCT was found.
    NvU32               BctBlock;

    /// Specifies the page number of the start of the BCT that was found.
    NvU32               BctPage; 

    /// Specifies the size of the BCT in bytes.  It is 0 until BCT loading
    /// is attempted.
    NvU32               BctSize;  /* 0 until BCT loading is attempted */

    /// Specifies a pointer to the BCT in memory.  It is NULL until BCT
    /// loading is attempted.  The BCT in memory is the last BCT that
    /// the BR tried to load, regardless of whether the operation was
    /// successful.
//    NvBootConfigTable  *BctPtr;
    void                *BctPtr;

    /// Specifies the state of attempting to load each of the BLs.
    NvBootBlState       BlState[NVBOOT_MAX_BOOTLOADERS];

    /// Specifies device-specific status information from the operation
    /// of the secondary boot device.
    NvBootSecondaryDeviceStatus SecondaryDevStatus;

    /// Specifies the lowest iRAM address that preserves communicated data.
    /// SafeStartAddr starts out with the address of memory following
    /// the BIT.  When BCT loading starts, it is bumped up to the 
    /// memory following the BCT.
    NvU32               SafeStartAddr;

} NvBootInfoTable;

#if defined(__cplusplus)
}
#endif

#endif /* #ifndef INCLUDED_NVBOOT_BIT_H */
